﻿//-----------------------------------------------------------------------
// <copyright file="WorkItem.cs" company="Microsoft Corporation">
//     Copyright Microsoft Corporation. All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) This is sample code only, do not use in production environments.
// </copyright>
//-----------------------------------------------------------------------

namespace VisualStudioOnlineOData.Models
{
    using System;
    using System.Globalization;
    using System.Xml.Linq;
    using VisualStudioOnlineOData.Utilities;

    /// <summary>
    ///
    /// </summary>
    public class WorkItem
    {
        private string _description;
        private string _productOwner;
        private string _project;
        private string _projectLead;
        private string _ruckMaster;
        private DateTimeOffset _scheduled = DateTimeOffsetTools.Base();
        private DateTime? _dateLanded = null;
        private string _scheduledStatus;
        private string _status;
        private string _state;
        private string _version;
        private string _webEditorUrl;
        private int? _workitemid;
        private string _workitemType;

        /// <summary>
        /// Gets or sets the content.
        /// </summary>
        /// <value>
        /// The content.
        /// </value>
        public WorkItemContent Content { get; set; }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>
        /// The description.
        /// </value>
        public string Description
        {
            get
            {
                if (_description == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _description = Content.Properties.Description;
                }

                return _description;
            }
            set
            {
                _description = value;
            }
        }

        /// <summary>
        /// Gets or sets the identifier.
        /// </summary>
        /// <value>
        /// The identifier.
        /// </value>
        public string Id { get; set; }

        /// <summary>
        /// Gets or sets the original position.
        /// </summary>
        /// <value>
        /// The original position.
        /// </value>
        public int OriginalPosition { get; set; }

        /// <summary>
        /// Gets or sets the product owner.
        /// </summary>
        /// <value>
        /// The product owner.
        /// </value>
        public string ProductOwner
        {
            get
            {
                if (_productOwner == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _productOwner = Content.Properties.ProductOwner;
                }

                return _productOwner;
            }
            set
            {
                _productOwner = value;
            }
        }

        /// <summary>
        /// Gets or sets the project.
        /// </summary>
        /// <value>
        /// The project.
        /// </value>
        public string Project
        {
            get
            {
                if (_project == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _project = Content.Properties.Project;
                }

                return _project;
            }
            set
            {
                _project = value;
            }
        }

        /// <summary>
        /// Gets or sets the project lead.
        /// </summary>
        /// <value>
        /// The project lead.
        /// </value>
        public string ProjectLead
        {
            get
            {
                if (_projectLead == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _projectLead = Content.Properties.ProjectLead;
                }

                return _projectLead;
            }
            set
            {
                _projectLead = value;
            }
        }

        /// <summary>
        /// Gets or sets the ruck master.
        /// </summary>
        /// <value>
        /// The ruck master.
        /// </value>
        public string RuckMaster
        {
            get
            {
                if (_ruckMaster == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _ruckMaster = Content.Properties.RuckMaster;
                }

                return _ruckMaster;
            }
            set
            {
                _ruckMaster = value;
            }
        }

        /// <summary>
        /// Gets or sets the scheduled.
        /// </summary>
        /// <value>
        /// The scheduled.
        /// </value>
        public DateTimeOffset Scheduled
        {
            get
            {
                if (_scheduled == DateTimeOffsetTools.Base())
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return DateTimeOffsetTools.Base();
                    }

                    return _scheduled = Content.Properties.Scheduled;
                }

                return _scheduled;
            }
            set
            {
                _scheduled = value;
            }
        }

        public DateTime? DateLanded
        {
            get
            {
                if (_dateLanded == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return null;
                    }

                    return _dateLanded = Content.Properties.DateLanded;
                }

                return _dateLanded;
            }
            set
            {
                _dateLanded = value;
            }
        }

        /// <summary>
        /// Gets or sets the scheduled status.
        /// </summary>
        /// <value>
        /// The scheduled status.
        /// </value>
        public string ScheduledStatus
        {
            get
            {
                if (_scheduledStatus == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _scheduledStatus = Content.Properties.ScheduledStatus;
                }

                return _scheduledStatus;
            }
            set
            {
                _scheduledStatus = value;
            }
        }

        /// <summary>
        /// Gets or sets the status.
        /// </summary>
        /// <value>
        /// The status.
        /// </value>
        public string Status
        {
            get
            {
                if (_status == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _status = Content.Properties.Status;
                }

                return _status;
            }
            set
            {
                _status = value;
            }
        }

        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        /// <value>
        /// The title.
        /// </value>
        public string Title { get; set; }

        public string State
        {
            get
            {
                return _state;
            }
            set
            {
                _state = value;
                if (value == "Done")
                {
                    Status = "Landed";
                }
            }
        }

        /// <summary>
        /// Gets or sets the version.
        /// </summary>
        /// <value>
        /// The version.
        /// </value>
        public string Version
        {
            get
            {
                if (_version == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _version = Content.Properties.Version;
                }

                return _version;
            }
            set
            {
                _version = value;
            }
        }

        /// <summary>
        /// Gets or sets the web editor URL.
        /// </summary>
        /// <value>
        /// The web editor URL.
        /// </value>
        public string WebEditorUrl
        {
            get
            {
                if (_webEditorUrl == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _webEditorUrl = Content.Properties.WebEditorUrl;
                }

                return _webEditorUrl;
            }
            set
            {
                _webEditorUrl = value;
            }
        }

        /// <summary>
        /// Gets or sets the work item identifier.
        /// </summary>
        /// <value>
        /// The work item identifier.
        /// </value>
        public int WorkItemId
        {
            get
            {
                if (!_workitemid.HasValue)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(int);
                    }

                    _workitemid = Content.Properties.Id;
                }

                return _workitemid.Value;
            }
            set
            {
                _workitemid = value;
            }
        }

        /// <summary>
        /// Gets or sets the type of the work item.
        /// </summary>
        /// <value>
        /// The type of the work item.
        /// </value>
        public string WorkItemType
        {
            get
            {
                if (_workitemType == null)
                {
                    if (Content == null || Content.Properties == null)
                    {
                        return default(string);
                    }

                    return _workitemType = Content.Properties.Type;
                }

                return _workitemType;
            }
            set
            {
                _workitemType = value;
            }
        }

        /// <summary>
        /// Froms the XML.
        /// </summary>
        /// <param name="xml">The XML.</param>
        /// <returns></returns>
        public static WorkItem FromXML(XElement xml)
        {
            return new WorkItem()
            {
                Id = xml.Attribute("id").Value,
                Title = xml.Attribute("title").Value,
                State = xml.Attribute("state").Value,
                _workitemid = Int32.Parse(xml.Attribute("workItemId").Value, CultureInfo.InvariantCulture),
                _workitemType = xml.Attribute("workItemType").Value,
                _project = xml.Attribute("project").Value,
                _webEditorUrl = xml.Attribute("webEditorUrl").Value,
                _productOwner = xml.Attribute("productOwner").Value,
                _projectLead = xml.Attribute("projectLead").Value,
                _ruckMaster = xml.Attribute("ruckMaster").Value,
                _status = xml.Attribute("status").Value,
                _version = xml.Attribute("version").Value,
                _scheduledStatus = xml.Attribute("scheduledStatus").Value,
                _scheduled = DateTimeOffset.ParseExact(xml.Attribute("scheduled").Value, "yyyy-MM-dd", CultureInfo.InvariantCulture),
                _dateLanded = xml.Attribute("dateLanded").Value == "N/A" ? (DateTime?)null : DateTime.ParseExact(xml.Attribute("dateLanded").Value, "yyyy-MM-dd", CultureInfo.InvariantCulture),
                _description = xml.Value,
                OriginalPosition = Int32.Parse(xml.Attribute("originalposition").Value)
            };
        }

        /// <summary>
        /// To the XML.
        /// </summary>
        /// <returns></returns>
        public XElement ToXML()
        {
            return new XElement("workitem",
                new XAttribute("id", Id),
                new XAttribute("title", Title ?? ""),
                new XAttribute("state", State ?? ""),
                new XAttribute("workItemId", WorkItemId),
                new XAttribute("workItemType", WorkItemType ?? ""),
                new XAttribute("project", Project ?? ""),
                new XAttribute("webEditorUrl", WebEditorUrl ?? ""),
                new XAttribute("productOwner", ProductOwner ?? ""),
                new XAttribute("projectLead", ProjectLead ?? ""),
                new XAttribute("ruckMaster", RuckMaster ?? ""),
                new XAttribute("status", Status ?? ""),
                new XAttribute("version", Version ?? ""),
                new XAttribute("scheduled", Scheduled.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)),
                new XAttribute("dateLanded", (DateLanded.HasValue ? DateLanded.Value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) : "N/A")),
                new XAttribute("scheduledStatus", ScheduledStatus ?? ""),
                new XAttribute("originalposition", OriginalPosition),
                new XCData(Description));
        }
    }
}